;^Z80^ TITLE FILE: TAPE_MANA:TOS HEWLETT-PACKARD: TAPE_MANAGER (c) Coleco 1983 Confidential ;NAME ^Rev 6 - DTT^ DESCR_ MACRO .GOTO ENDESCR_1 Author: DTT Project: ________, ___ Starting date:18feb83 Prom release Date: Prom release Rev: Header Rev: 3 ******************************** * * * TAPE_MANAGER DTT * * * ******************************** Rev History (one line note indicating the change) Rev. Date Name Change 6 11/16/83 DTT ADDED DEVICE ID TO SIMULATE DEVICE INDEPENDENCE 5 12spt83 DTT MODIFIED ERROR SYSTEM TO WRITE ERRORS TO CSA AREA 4 08aug83 DTT SIMULATES WRITES! 3 07jul83 DTT ADDED KILL_TAPE/CSA 2 30jun83 DTT STATE MACHINE FOR MULTI TASKING 1 05apr83 DTT BINK ON I/O ERROR, REMOVING TIMING STUFF, EI AND DI ADDED. 0 10feb83 DTT Initial Pseudo Code NAME: TAPE_MANAGER (OVERLAY CONTROL) FUNCTION: (LOAD OVERLAYS VIA SIMULATED I/O WITH THE HP64000) INPUTS: (ACCUMULATOR = OVERLAY NUMBER) OUTPUTS: (OVERLAY IS LOADED TO RAM ADDRESS) PSEUDOCODE: (PASCAL type pseudocode of procedure.) ---------------- overlay request? Y ---------------- : :-----------------------> : : :---->: IDLE : : RENAME : : : : : : : : :---------: : : : ---------------- : ---------------- : /:\ overlay request? N : : :______________: : : : : : : : : : : : : : : \:/ : ---------------- ---------------- : : : : : : : READ : <--------------------------: OPEN : : : FIRST : : : : : RECORD : : : : ------:--------- ---------------- : : : : : \:/ : ---------------- ---------------- : : :------------------------> : : : : READ : : MOVE DATA : : : DATA : end of file? N : FROM BUFFER : : : RECORD : <--------------------------: TO RAM : : ---------------- --------:------- : : : end of file? Y : \:/ : ---------------- ---------------- : : : : : -----: PRE IDLE STATE :<---------------------------: CLOSE : :(WAIT FOR CLOSE): : : : : : : ---------------- ---------------- ENDESCR_1 MEND DESC_a MACRO .GOTO DESC_a *********************************************************************************************** Each transition state looks like this: from previous =================: state : \:/ ----------------: ----------------- : : I/O errors? Y : : : TRANSITION :-------------------> : ERROR STATE : :===>: : : (terminate) :----: : : :=====: : : : : ---------------- : ----------:------ : : : : /:\ : : : : : : : sim i/o : \:/ :___________: ------------ ---------------- to state 6 function : :============> complete? N : TEST FOR : : ABORT :to state 7 : REQUEST :============> ---------------- no : abort : to next : state \:/ DESC_a MEND DESC_2 MACRO .GOTO DESC_2 * *************************************************************************************** * COMMON ATTRIBUTE AREAS (COMMUNICATION BUFFER WITH HP) ALL VALUES ARE HEXADECIMAL 1) ASSIGN FILENAME TO CA CA CA+1 CA+2 CA+n -------- -------- -------- -------- -------- -------- -------- -------- : 8A :LENGTH :FILENAME ------> : USER ID : NOT : :BYTE :UP TO 9 BYTES : UP TO 5 BYTES : USED-----> -------- -------- -------- -------- -------- -------- -------- -------- LENGTH_BYTE := (((((LENGTH OF FILE NAME)+1)/2)-1)*32) + ((LENGTH OF USER ID)/2)*8) FILENAME MUST BE ODD NUMBER OF BYTES LONG MAY BE PADDED WITH ONE SPACE. USER ID MUST BE EVEN NUMBER OF BYTES LONG MAY BE PADDED WITH ONE SPACE. 2) OPEN CA CA+1 CA+2 -------- -------- -------- -------- -------- -------- -------- -------- : 81 : 04 : 00 : NOT : : : : USED-------------------------------> -------- -------- -------- -------- -------- -------- -------- -------- CA+1 MUST BE 04HEX DESIGNATES ABSOLUTE FILE WILL BE OPENED. CA+2 MUST BE 00HEX DESIGNATES DISK NUMBER. 3) CLOSE CA -------- -------- -------- -------- -------- -------- -------- -------- : 82 : NOT : : USED -----------------------------------------------> -------- -------- -------- -------- -------- -------- -------- -------- 4) READ CA CA+1 CA+2 CA+4 CA+6 -------- -------- -------- -------- -------- -------- -------- -------- : 87 : 80 : #BYTES TO LOAD : N/A : N/A : LOAD ADDRESS : : : MSB : LSB : : : MSB : LSB -------- -------- -------- -------- -------- -------- -------- -------- CA+1 DEFINES THE BUFFER LENGTH IN WORDS - 1 MUST BE LOADED BEFORE CALLING SIM I/O CA+2 DEFINES NUMBER OF BYTES TO MOVE TO RAM FROM THE SIM I/O BUFFER CA+6 DEFINES THE RAM ADDRESS TO LOAD TO CA+8 (NOT SHOWN) IS THE START OF THE SIM I/O BUFFER NOTE: CA+2 AND CA+6 ARE ONE WORD LONG BUT NOT STORED AS Z80 WORDS. THE Z80 EXPECTS WORD VALUES TO BE STORED LSB/MSB. DESC_2 MEND NEXT_STATE MACRO LP1 LD A,LP1 ;SOMETHING IN THE COMMAND BUFFER! LD [TAPE_STATE],A LD HL,[STATE_VECTORS+LP1+LP1] LD [NEXT_STATE_ADDRESS],HL JP END_OF_STATE_MACHINE MEND ;SUBROUTINES CALLED: ; EXT ;OPERATING SYSTEM CALLS: ;EXTERNAL DATA AREAS USED: EXT KILL_TAPE EXT WRITE_TAPE EXT CSA EXT TAPE_STATE EXT OVERLAY_NUMBER ;GLOBAL DATA AREAS DEFINED: GLOBAL DEVICE_ID ;LOCAL EQUATES CA EQU 07400H ;COMMON ATTRIBUTES AREA FOR SIM I/O BUF_LEN EQU CA+1 FILETYPE EQU CA+1 ;FILETYPE ADDRESS IN C_A_ DISC_NUM EQU FILETYPE+1 ;DISK NUMBER ADDRESS IN C_A_ REC_LEN EQU CA+2 ;RECORD LENGTH ADDRESS IN C_A_ BUFFER EQU CA+8 ;I_O_BUFFER RNAM_BUF EQU CA+1 ;RENAME BUFFER AREA LOADADDR EQU CA+4 ;ADDRESS OF MEM ADDRESS OF OVERLAY MAXBUFLN EQU 128 ;UP TO 128 WORDS MAY BE READ IN ABSOLUTE EQU 004H ;FILE TYPE IS ABSOLUTE OPEN EQU 081H CLOSE EQU 082H READ EQU 087H WRITE EQU 089H RENAME EQU 08AH ;GLOBAL EQUATES ; INCLUDE equate file name PROG GLOBAL TAPE_MANAGER GLOBAL INITIALIZE_TAPE INITIALIZE_TAPE: GLOBAL INIT_TAPE INIT_TAPE: LD A,0 ;CLEAR THE HP64000 AREA LD [CA],A LD [CSA],A ;AND THE TAPE CONTROL STATUS AREA DEC A LD [OVERLAY_NUMBER],A ;MAKE THE OVERLAY NUMBER -1 (INVALID) NEXT_STATE 0 ;SET THE IDLE STATE! RET TAPE_MANAGER: ;BEGIN (Ordinarily registers are restored; retain only the pushes and pops you need.) LD A,[CA] ;TEST THE STATUS OF THE FILE OR A JP M,END_OF_STATE_MACHINE ;IF THERE IS A COMMAND IN THE BUFFER JR Z,AB_REQ CP 1 ;END OF FILE ON READ FROM HP64000 JP NZ,ERROR ;* ;* AT THIS POINT ANY SIM I/O FUNCTIONS ARE COMPLETE; TEST FOR ABORTS (KILLS) ;* GLOBAL AB_REQ AB_REQ: LD A,[CSA] ;IF COMMAND IS TO KILL TAPE COMMAND CP KILL_TAPE JR NZ,CASE_STATE LD A,[TAPE_STATE] ;CHECK THE STATE OF THE TAPE ;* CP 3 ;CHECK STATE 0,1,2 JP C,STATE_PRE_IDLE ;FILE NOT OPENED ;* CP 6 ;STATE 3,4,5 JP C,STATE_CLOSE ;FILE OPENED TRY TO CLOSE IT ;* ;* FALL THRU TO CASE STATEMENT ;IF STATE = 6,7 ;* ;FILE IS TRYING TO CLOSE ;* ;* ;* CASE TAPE_STATE,(IDLE,RENAME,OPEN,READ1,READ2,MOVE2VRAM,CLOSE,PRE_IDLE) ;* CASE_STATE: ;* ;* LD HL,[NEXT_STATE_ADDRESS] JP [HL] STATE_VECTORS: DEFW STATE_IDLE ;STATE 0 DEFW STATE_RENAME ; 1 DEFW STATE_OPEN ; 2 DEFW STATE_READ_1 ; 3 DEFW STATE_READ_2 ; 4 DEFW STATE_MOVE2RAM ; 5 DEFW STATE_CLOSE ; 6 DEFW STATE_PRE_IDLE ; 7 DEFW WRITE_1 ;* ;* IF THE MACHINE IS IDLE IT'S OK TO TEST FOR ANOTHER READ REQUEST ;* STATE_IDLE: ;STATE 0 LD A,[CSA] ;TEST THE COMMAND STATUS AREA OR A JP Z,END_OF_STATE_MACHINE ;* NEXT_STATE 1 ;* ;* ASSIGN THE SIM I/O FILE TO THE CURRENT OVERLAY NAME ;* STATE_RENAME: ;STATE 1 LD A,[OVERLAY_NUMBER] LD HL,SAMPLE_NAME LD DE,RNAM_BUF ;POINT TO THE RENAME BUFFER IN THE COMMON ATTRIBUTES AREA LD BC,SAMPLE_NAME_LEN ;NO NAME COULD BE MORE THAN TEN BYTES LONG COULD IT? LDIR ;MOVE THE OVERLAY DATA TO THE RENAME BUFFER ;* ;* ;* LD BC,10*256+"0" ;GET THE OVERLAY NUMBER INTO ASCII OV_2_ASCII_1: OR A SBC A,B ;DIVIDE OVERLAY NUMBER BY 10 INC C ;SET THE NUMBER OF TENS IN C (DOESN'T RESET CARRY) JR NC,OV_2_ASCII_1 ;CARRY WAS SET BY SUBTRACT IF B>A DEC C ;SAVE THE TENS BYTE ADD A,B ;ADD TENS TO GET THE REMAINDER LD B,"0" ;SAVE THE ONES BYTE ADD A,B LD B,A LD A,C CP "0" ;CONVERT TO ASCII JR NZ,OV_2_ASCII_2 LD A,"_" ;SPECIAL CASE OV_2_ASCII_2: LD [DE],A ;DE IS POINTING TO THE FILENAME FROM THE LDIR ABOVE INC DE LD A,B LD [DE],A ;* ;* ASSIGN THE FILE ;* LD A,RENAME LD [CA],A ;* NEXT_STATE 2 ;NEXT OPEN ;* ;* STATE_OPEN: ;STATE 2 ;* ;* OPEN THE FILE ;* LD A,ABSOLUTE ;LOAD THE FILE TYPE LD [FILETYPE],A LD A,0 ;DISK NUMBER LD [DISC_NUM],A LD A,OPEN ;OPEN THE CURRENT FILE LD [CA],A LD A,[CSA] ;NEXT STATE READ OR WRITE? NEXT_STATE 3 ;NEXT STATE = READ_1 STATE_READ_1: ;STATE 3 ;* ;* READ THE FIRST RECORD TO SKIP OVER IT ;* LD A,MAXBUFLN ;SET THE INPUT BUFFER LENGTH LD [BUF_LEN],A ; LD A,READ LD [CA],A ;READ THE FIRST RECORD NEXT_STATE 4 ;* ;* READ REMAINING RECORDS AND MOVE TO RAM ;* STATE_READ_2: ;STATE 4 LD A,MAXBUFLN ;SET THE INPUT BUFFER LENGTH LD [BUF_LEN],A ; LD A,READ ; LD [CA],A NEXT_STATE 5 ;NEXT STATE = READ A DATA RECORD ;* ;* MOVE THE LAST BUFFER TO RAM ;* STATE_MOVE2RAM: ;STATE 5 LD A,[CA] ;CHECK THE RETURN STATUS OR A JR Z,NO_EOF ;END OF FILE? ;* ;* NEXT_STATE 6 ;NEXT STATE = CLOSE FILE NO_EOF: ;MOVE THE CURRENT OVERLAY TO MEMORY LD HL,[REC_LEN] ;GET THE NUMBER OF BYTES TO MOVE TO RAM LD C,H LD B,L ;* LD HL,[LOADADDR] ;GET THE LOAD ADDRESS AND CHECK TO SEE IF IT IS IN VRAM LD D,L LD E,H LD HL,BUFFER ;FROM ADDRESS LD A,[CSA] CP WRITE_TAPE JR Z,WRITE_1 LDIR ;* NEXT_STATE 4 ;NEXT STATE = READ A DATA RECORD ;* ;* CLOSE OVERLAY FILE ;* STATE_CLOSE: ;STATE 6 LD A,CLOSE ;CLOSE THE FILES LD [CA],A NEXT_STATE 7 ;NEXT STATE = PRE-IDLE ;* ;* ;* NEXT STATE IS IDLE ;* STATE_PRE_IDLE: ;STATE 7 LD A,0 ;NEXT STATE = PRE-IDLE LD [CSA],A ;CLEAR THE COMMAND STATUS BUFFER DEC A LD [OVERLAY_NUMBER],A ;SET THE OVERLAY NUMBER TO OUT OF RANGE NEXT_STATE 0 ;* ;* WRITE OUT 256 DATA BYTES TO AN OVERLAY! OH BOY! ;* WRITE_1: ;GET HERE FROM MOVE2RAM1 EX DE,HL LDIR LD A,WRITE LD [CA],A NEXT_STATE 6 ;* ;* ;* ; END (TAPE_MANAGER) END_OF_STATE_MACHINE: XOR A RET ;*************************************************************************** ;*************************************************************************** ERROR: ; BEGIN (Ordinarily registers are restored; retain only the pushes and pops you need.) LD C,A LD A,[OVERLAY_NUMBER] ;SAVE THE OVERLAY NUMBER IN A LD B,A LD A,[TAPE_STATE] LD HL,0 ;B HAS THE FUNCTION CODE LD [HL],A ;C HAS THE ERROR CODE ; ; LD [HL] HAS JUST CAUSED A BINK TO OCCUR ON THE HP64000 ; THIS IS TO LET THE USER KNOW THERE HAS BEEN AN ERROR ; XOR A LD [CA],A ;CLEAR THE ERROR FROM THE HP64000 INC A ;PRETEND THE ERROR WAS A CRC CHECK FROM ADAM'S TAPE LD [CSA],A LD HL,[STATE_VECTORS+0000] LD [NEXT_STATE_ADDRESS],HL RET ; END (TAPE_ERR) ;*************************************************************************** ;*************************************************************************** ; ; OVERLAY NAMES ; ; -------- -------- -------- -------- -------- ; :LENGTH :FILENAME ------> : USER ID : ; :BYTE :UP TO 9 BYTES : UP TO 5 BYTES : ; -------- -------- -------- -------- -------- ; LENGTH_BYTE := (((((LENGTH OF FILE NAME)+1)/2)-1)*32) + ((LENGTH OF USER ID)/2)*8) ; FILENAME MUST BE ODD NUMBER OF BYTES LONG MAY BE PADDED WITH ONE SPACE. ; USER ID MUST BE EVEN NUMBER OF BYTES LONG MAY BE PADDED WITH ONE SPACE. ; ;***************************************************************************************** ;***************************************************************************************** ;* ;* OVERLAY NAME 0 ;* SAMPLE_NAME OVLAY0 DEFB FL_NM_LN0*32+US_ID_LN0*8 ;LENGTH DESCRIPTION BYTE NAM_0 DEFB "OVL_1" ;MUST BE ODD NUMBER OF LETTERS USID0 DEFB "" ;MUST BE EVEN NUMBER OF LETTERS FL_NM_LN0 EQU ((USID0-NAM_0+1)/2)-1 ;LENGTH OF FILENAME IN WORDS US_ID_LN0 EQU ($-USID0)/2 ;LENGTH OF USERID IN WORDS SAMPLE_NAME_LEN EQU $-SAMPLE_NAME-2 ;NUMBER OF BYTES TO MOVE = 4 ;*********************************************************************** DATA GLOBAL NEXT_STATE_ADDRESS NEXT_STATE_ADDRESS DEFS 2 ;POINTER TO NEXT ENTRY STATE DEVICE_ID DEFS 1 ;DEVICE INDEPENDENCE SIMULATED